// 错误类型定义
export enum ErrorType {
  NETWORK = 'NETWORK',
  API = 'API',
  VALIDATION = 'VALIDATION',
  CACHE = 'CACHE',
  UNKNOWN = 'UNKNOWN'
}

export interface AppError {
  type: ErrorType
  message: string
  originalError?: Error
  code?: string | number
  timestamp: Date
  context?: Record<string, any>
}

// 错误处理类
export class ErrorHandler {
  private static instance: ErrorHandler
  private errorLog: AppError[] = []
  private maxLogSize = 100

  private constructor() {}

  static getInstance(): ErrorHandler {
    if (!ErrorHandler.instance) {
      ErrorHandler.instance = new ErrorHandler()
    }
    return ErrorHandler.instance
  }

  // 创建应用错误
  createError(
    type: ErrorType,
    message: string,
    originalError?: Error,
    context?: Record<string, any>
  ): AppError {
    const appError: AppError = {
      type,
      message,
      originalError,
      timestamp: new Date(),
      context
    }

    // 记录错误
    this.logError(appError)

    return appError
  }

  // 记录错误
  private logError(error: AppError): void {
    this.errorLog.unshift(error)
    
    // 限制日志大小
    if (this.errorLog.length > this.maxLogSize) {
      this.errorLog = this.errorLog.slice(0, this.maxLogSize)
    }

    // 在开发环境下打印错误
    if (process.env.NODE_ENV === 'development') {
      console.error('App Error:', error)
    }
  }

  // 获取错误日志
  getErrorLog(): AppError[] {
    return [...this.errorLog]
  }

  // 清除错误日志
  clearErrorLog(): void {
    this.errorLog = []
  }

  // 处理网络错误
  handleNetworkError(error: Error, context?: Record<string, any>): AppError {
    let message = '网络连接失败，请检查网络设置'
    
    if (error.message.includes('timeout')) {
      message = '请求超时，请稍后重试'
    } else if (error.message.includes('fetch')) {
      message = '网络请求失败，请检查网络连接'
    }

    return this.createError(ErrorType.NETWORK, message, error, context)
  }

  // 处理 API 错误
  handleApiError(
    status: number,
    statusText: string,
    data?: any,
    context?: Record<string, any>
  ): AppError {
    let message = 'API 请求失败'
    
    switch (status) {
      case 400:
        message = '请求参数错误'
        break
      case 401:
        message = 'API 密钥无效或已过期'
        break
      case 403:
        message = '访问被拒绝，请检查权限'
        break
      case 404:
        message = '请求的资源不存在'
        break
      case 429:
        message = '请求过于频繁，请稍后重试'
        break
      case 500:
        message = '服务器内部错误'
        break
      case 502:
      case 503:
      case 504:
        message = '服务暂时不可用，请稍后重试'
        break
      default:
        message = `请求失败 (${status}): ${statusText}`
    }

    return this.createError(ErrorType.API, message, undefined, {
      status,
      statusText,
      data,
      ...context
    })
  }

  // 处理验证错误
  handleValidationError(message: string, context?: Record<string, any>): AppError {
    return this.createError(ErrorType.VALIDATION, message, undefined, context)
  }

  // 处理缓存错误
  handleCacheError(error: Error, context?: Record<string, any>): AppError {
    const message = '缓存操作失败'
    return this.createError(ErrorType.CACHE, message, error, context)
  }

  // 处理未知错误
  handleUnknownError(error: Error, context?: Record<string, any>): AppError {
    const message = error.message || '发生未知错误'
    return this.createError(ErrorType.UNKNOWN, message, error, context)
  }

  // 获取用户友好的错误消息
  getUserFriendlyMessage(error: AppError): string {
    switch (error.type) {
      case ErrorType.NETWORK:
        return error.message + '，请检查网络连接后重试'
      case ErrorType.API:
        return error.message + '，如果问题持续存在，请联系管理员'
      case ErrorType.VALIDATION:
        return error.message
      case ErrorType.CACHE:
        return '数据缓存出现问题，请刷新页面重试'
      case ErrorType.UNKNOWN:
        return '发生未知错误，请刷新页面或稍后重试'
      default:
        return '发生错误，请稍后重试'
    }
  }

  // 判断错误是否可重试
  isRetryable(error: AppError): boolean {
    switch (error.type) {
      case ErrorType.NETWORK:
        return true
      case ErrorType.API:
        // 5xx 错误和 429 错误可重试
        const status = error.context?.status
        return status >= 500 || status === 429
      case ErrorType.CACHE:
        return true
      default:
        return false
    }
  }
}

// 导出单例实例
export const errorHandler = ErrorHandler.getInstance()

// 便捷函数
export const handleError = (error: Error, context?: Record<string, any>): AppError => {
  if (error.name === 'TypeError' && error.message.includes('fetch')) {
    return errorHandler.handleNetworkError(error, context)
  }
  
  return errorHandler.handleUnknownError(error, context)
}

// React Hook 用于错误处理
export const useErrorHandler = () => {
  const handleNetworkError = (error: Error, context?: Record<string, any>) => 
    errorHandler.handleNetworkError(error, context)
  
  const handleApiError = (status: number, statusText: string, data?: any, context?: Record<string, any>) =>
    errorHandler.handleApiError(status, statusText, data, context)
  
  const handleValidationError = (message: string, context?: Record<string, any>) =>
    errorHandler.handleValidationError(message, context)
  
  const handleCacheError = (error: Error, context?: Record<string, any>) =>
    errorHandler.handleCacheError(error, context)
  
  const handleUnknownError = (error: Error, context?: Record<string, any>) =>
    errorHandler.handleUnknownError(error, context)
  
  const getUserFriendlyMessage = (error: AppError) =>
    errorHandler.getUserFriendlyMessage(error)
  
  const isRetryable = (error: AppError) =>
    errorHandler.isRetryable(error)
  
  const getErrorLog = () => errorHandler.getErrorLog()
  const clearErrorLog = () => errorHandler.clearErrorLog()

  return {
    handleNetworkError,
    handleApiError,
    handleValidationError,
    handleCacheError,
    handleUnknownError,
    getUserFriendlyMessage,
    isRetryable,
    getErrorLog,
    clearErrorLog
  }
}